package edu.nyu.hps.architecture;

import java.util.ArrayList;

/**
 * This class handles the message protocol between the players and the server
 * 
 * @author hiralrajani
 * 
 */
public class Protocol {
	int count = 0, catX, catY, mouseX, mouseY;
	Player player, opponent;

	public Protocol(Player p, Player o) {
		this.player = p;
		this.opponent = o;
	}

	/**
	 * Processes the messages from the client and the server
	 * 
	 * @param theInput
	 *            from the client (mouse or cat)
	 * @return message
	 */
	public String processInput(String theInput) {
		String[] input = theInput.split(":");
		if (count == 0) {
			count++;
			if (input[0].equals("JOIN")) {
				player.name = input[1];
				setPositions();
				
				int p = player.who.equals("cat") == true ? 0 : 1;
				return "ACK:" + p + ":" + player.x + "," + player.y + "\n"
						+ "PLAY:" + player.time + ":" + catX + "," + catY + ":"
						+ mouseX + "," + mouseY;
			} else {
				System.out.println("NACK:Invalid input");
				return "NACK:Invalid input";
			}

		} else {
			count++;
			// To check for valid input from the player
			if (input[0].equals("MOVE")) {
				// TO check for valid move of the player
				if (player.validMove(input)) {
					boolean gameOver = gameProcess(input);
					if (gameOver) {

						// Printing last moves of cat
						ArrayList<Point> temp = player.pastMoves
								.get(player.totalMoves + 1);
						System.out.print("Turn " + (player.totalMoves + 1)
								+ "  :  " + player.who + "  :  " + "MOVE");
						for (int i = 0; i < temp.size(); i++) {
							System.out.print(":");
							System.out.print(temp.get(i).x + ","
									+ temp.get(i).y);
						}
						System.out.println();
						
						//Printing last move of mouse
						temp = opponent.pastMoves.get(opponent.totalMoves);
						System.out.println("Turn " + (opponent.totalMoves)
								+ "  :  " + opponent.who + "  :  " + "MOVE:"
								+ temp.get(0).x + "," + temp.get(0).y);
						
						//Setting the status in each object
						player.caught = true;
						opponent.caught = true;
						
						return "STATUS:MOUSE CAUGHT IN "
								+ (opponent.totalMoves) + " TURNS";
					}
					
				} else {
					System.out.println("NACK:Invalid Move");
					return "NACK:Invalid Move";
				}

				// Mouse waits for cat to complete its move
				if (player.who.equals("mouse")) {
					while (!opponent.ready) {
						System.out.print("");
						if (player.caught == true) {
							return "STATUS:MOUSE CAUGHT IN "
									+ (player.totalMoves) + " TURNS";
						}
						// Waiting for cat to finish it's move
					}
					opponent.ready = false;
				}
				// Setting positions for mouse and cat
				setPositions();

				System.out.println("Turn " + player.totalMoves + "  :  "
						+ player.who + "  :  " + theInput);
				return "PLAY:" + player.time + ":" + catX + "," + catY + ":"
						+ mouseX + "," + mouseY;
			} else {
				System.out.println("NACK:Invalid Move");
				return "NACK:Invalid input";
			}
		}
	}

	/**
	 * Tracing the actual move of cat and mouse
	 * 
	 * @param move
	 * @return true if the mouse is caught, false otherwise.
	 */
	public boolean gameProcess(String[] move) {
		int count = 0;
		ArrayList<Point> mouseMove = new ArrayList<Point>();
		if (player.who.equals("mouse")) {
			player.x = Integer.parseInt(move[1].split(",")[0]);
			player.y = Integer.parseInt(move[1].split(",")[1]);
			mouseMove.add(new Point(player.x, player.y));
			player.totalMoves++;
			player.pastMoves.put(player.totalMoves, mouseMove);
			while (player.totalMoves <= opponent.totalMoves) {
			}
			player.ready = true;
		} else {

			// Cat waits for mouse to complete its move
			while (!opponent.ready) {
				System.out.print("");
			}
			ArrayList<Point> catMove = new ArrayList<Point>();
			for (int i = 1; i < move.length; i++) {
				count++;
				player.x = Integer.parseInt(move[i].split(",")[0]);
				player.y = Integer.parseInt(move[i].split(",")[1]);
				catMove.add(new Point(player.x, player.y));
				if (player.x == opponent.x && player.y == opponent.y) {
					player.pastMoves.put(player.totalMoves + 1, catMove);
					return true;
				}
			}
			player.totalMoves++;
			player.pastMoves.put(player.totalMoves, catMove);
			while (player.totalMoves < opponent.totalMoves) {
			}
			opponent.ready = false;
			player.ready = true;

		}
		return false;
	}

	/**
	 * This method sets the position locations for cat and mouse
	 */
	public void setPositions() {
		if (player.who.equals("cat")) {
			catX = player.x;
			catY = player.y;
			mouseX = opponent.x;
			mouseY = opponent.y;
		} else {
			catX = opponent.x;
			catY = opponent.y;
			mouseX = player.x;
			mouseY = player.y;
		}
	}
}
